package com.simpleplayer.engine;

import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Build;
import android.view.Surface;
import android.view.SurfaceHolder;

import com.simpleplayer.services.LogUtil;

import java.io.IOException;

class MediaPlayerEngine extends PlayerEngine {
    private static final String TAG = "MediaPlayerEngine";

    private MediaPlayer mPlayer;

    public MediaPlayerEngine() {
        ensurePlayerCreated();
    }

    private void ensurePlayerCreated() {
        if(mPlayer == null) {
            mPlayer = new MediaPlayer();
            mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
            MediaPlayerListener mediaPlayerListener = new MediaPlayerListener();
            mPlayer.setOnPreparedListener(mediaPlayerListener);
            mPlayer.setOnSeekCompleteListener(mediaPlayerListener);
            mPlayer.setOnCompletionListener(mediaPlayerListener);
            mPlayer.setOnBufferingUpdateListener(mediaPlayerListener);
            mPlayer.setOnInfoListener(mediaPlayerListener);
            mPlayer.setOnVideoSizeChangedListener(mediaPlayerListener);
        }
    }

    private MediaPlayer getPlayer() {
        ensurePlayerCreated();
        return mPlayer;
    }

    @Override
    public long getCurrentPosition() {
        return getPlayer().getCurrentPosition();
    }

    @Override
    public long getDuration() {
        return getPlayer().getDuration();
    }

    @Override
    public void prepare(String uri) {
        try {
            getPlayer().setDataSource(uri);
            // getPlayer().prepareAsync();
            getPlayer().prepare();
        } catch (IOException e) {
            getClient().onError();
        }

    }

    @Override
    public void play() {
        getPlayer().start();
    }

    @Override
    public void pause() {
        getPlayer().pause();
    }

    @Override
    public void release() {
        getPlayer().release();
    }

    @Override
    public void seekTo(long position) {
        // MediaPlayer 默认会跳转到关键帧，需要设置跳转到最接近时间
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            getPlayer().seekTo(position, MediaPlayer.SEEK_CLOSEST);
        } else {
            getPlayer().seekTo((int)position);
        }
    }

    @Override
    public void setSurface(Surface surface) {
        getPlayer().setSurface(surface);
    }

    @Override
    public void setDisplay(SurfaceHolder holder) {
        getPlayer().setDisplay(holder);
    }

    @Override
    public int getVideoHeight() {
        return getPlayer().getVideoHeight();
    }

    @Override
    public int getVideoWidth() {
        return getPlayer().getVideoWidth();
    }

    @Override
    public void setVolume(float volume) {
        getPlayer().setVolume(volume, volume);
    }

    private class MediaPlayerListener implements
            MediaPlayer.OnSeekCompleteListener,
            MediaPlayer.OnPreparedListener,
            MediaPlayer.OnCompletionListener,
            MediaPlayer.OnBufferingUpdateListener,
            MediaPlayer.OnInfoListener,
            MediaPlayer.OnVideoSizeChangedListener {

        @Override
        public void onSeekComplete(MediaPlayer mp) {
            getClient().onSeekComplete();
        }

        @Override
        public void onPrepared(MediaPlayer mp) {
            getClient().onPrepared();
        }

        @Override
        public void onCompletion(MediaPlayer mp) {
            getClient().onPlaybackComplete();
        }

        @Override
        public void onBufferingUpdate(MediaPlayer mp, int percent) {
            LogUtil.d(TAG, "onBufferingUpdate " + percent);
        }

        @Override
        public boolean onInfo(MediaPlayer mp, int what, int extra) {
            switch (what) {
                case MediaPlayer.MEDIA_INFO_BUFFERING_START:
                    LogUtil.d(TAG, "BUFFERING_START, value: " + extra);
                    getClient().onBufferingStart();
                    break;
                case MediaPlayer.MEDIA_INFO_BUFFERING_END:
                    LogUtil.d(TAG, "BUFFERING_END, value: " + extra);
                    getClient().onBufferingEnd();
                    break;
                case MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START:
                    LogUtil.d(TAG, "VIDEO_RENDERING_START, value: " + extra);
                    break;
                default:
                    break;
            }
            return false;
        }

        @Override
        public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
            getClient().onVideoSizeChanged(width, height);
        }
    }
}
